using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;

public class WebServer
{
    private TcpListener _listener;
    private Dictionary<string, X509Certificate2> _certificates;
    private bool _isRunning;
    private Dictionary<string, string> _responses;

    public WebServer(int port, Dictionary<string, string> certificatePaths, Dictionary<string, string> certificatePasswords, Dictionary<string, string> responses)
    {
        _certificates = new Dictionary<string, X509Certificate2>();
        foreach (var kvp in certificatePaths)
        {
            _certificates[kvp.Key] = new X509Certificate2(kvp.Value, certificatePasswords[kvp.Key]);
        }
        _listener = new TcpListener(IPAddress.Any, port);
        _responses = responses;
    }

    public void Start()
    {
        _isRunning = true;
        _listener.Start();
        _listener.BeginAcceptTcpClient(HandleClient, null);
    }

    private void HandleClient(IAsyncResult ar)
    {
        if (!_isRunning) return;

        try
        {
            using (var client = _listener.EndAcceptTcpClient(ar))
            using (var sslStream = new SslStream(client.GetStream(), false))
            {
                // 显式指定安全协议和加密策略
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, errors) => true;

                // 选择第一个证书作为默认证书
                var defaultCert = _certificates.First().Value;

                // SNI支持(兼容.NET Framework 4.5.2)
                sslStream.AuthenticateAsServer(
                    serverCertificate: defaultCert,
                    clientCertificateRequired: false,
                    enabledSslProtocols: System.Security.Authentication.SslProtocols.Tls12,
                    checkCertificateRevocation: false);

                // 从请求头中解析主机名(替代TargetHostName)
                string serverName = _certificates.Keys.First();
                byte[] buffer = new byte[4096];
                int bytesRead = 0;
                string request = "";

                try
                {
                    bytesRead = sslStream.Read(buffer, 0, buffer.Length);
                    request = Encoding.ASCII.GetString(buffer, 0, bytesRead);

                    // 从HTTP请求头中提取Host
                    var hostHeader = request.Split(new[] { "\r\n" }, StringSplitOptions.None)
                        .FirstOrDefault(line => line.StartsWith("Host:"));

                    if (hostHeader != null)
                    {
                        serverName = hostHeader.Split(':')[1].Trim();
                        if (!_certificates.ContainsKey(serverName))
                        {
                            serverName = _certificates.Keys.First();
                        }
                    }
                }
                catch
                {
                    // 如果解析失败，使用默认证书
                    serverName = _certificates.Keys.First();
                }

                // 根据域名获取响应
                string response = _responses.ContainsKey(serverName) ? _responses[serverName] : _responses.Values.First();
                byte[] responseBytes = Encoding.UTF8.GetBytes(response);
                sslStream.Write(responseBytes, 0, responseBytes.Length);
            }
        }
        catch (Exception ex)
        {
            // 使用 StreamWriter 写入文本
            using (StreamWriter writer = new StreamWriter("log.txt"))
            {
                writer.WriteLine(DateTime.Now.ToString() + ":" + ex.Message + "\r\n");
            }

        }
        finally
        {
            if (_isRunning)
                _listener.BeginAcceptTcpClient(HandleClient, null);
        }
    }

    public void Stop()
    {
        _isRunning = false;
        _listener.Stop();
    }
}
